package com.cjkj.system.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.cjkj.common.core.constant.*;
import com.cjkj.common.core.domain.PatVisitIntervalData;
import com.cjkj.common.core.domain.R;
import com.cjkj.common.core.exception.ServiceException;
import com.cjkj.common.core.utils.DateUtils;
import com.cjkj.common.core.utils.ObjectConversionUtils;
import com.cjkj.common.core.utils.StringUtils;
import com.cjkj.system.api.RemoteTJ01DataService;
import com.cjkj.system.api.domain.APIMonitorPadData;
import com.cjkj.system.api.domain.MonitorPadRecords;
import com.cjkj.system.api.domain.PatientSleepStageRecord;
import com.cjkj.system.api.domain.SleepStageRecords;
import com.cjkj.system.api.domain.request.RecordsReq;
import com.cjkj.system.api.domain.request.SleepStageReq;
import com.cjkj.system.domain.TEquipmentUsageRecords;
import com.cjkj.system.domain.TPatVisit;
import com.cjkj.system.domain.dto.TJ01ReportsDataReq;
import com.cjkj.system.domain.vo.*;
import com.cjkj.system.domain.vo.report.*;
import com.cjkj.system.mapper.TEquipmentUsageRecordsMapper;
import com.cjkj.system.mapper.TPatVisitMapper;
import com.cjkj.system.service.ReportTJ01Service;
import com.cjkj.system.util.ReportUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ReportTJ01ServiceImpl implements ReportTJ01Service {

    @Resource
    private TPatVisitMapper patVisitMapper;

    @Resource
    private TEquipmentUsageRecordsMapper equipmentUsageRecordsMapper;

    @Resource
    private RemoteTJ01DataService remoteTJ01DataService;

    @Override
    public SleepReportVo sleep(Long visitNo, Date reportDate) {
        // 获取患者开单时间和出院时间
        PatVisitIntervalData intervalData = getTimes(visitNo);
        Date visitTime = intervalData.getVisitTime();
        Date outTime = intervalData.getOutTime();

        Calendar cal = Calendar.getInstance();
        cal.setTime(reportDate);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        reportDate = cal.getTime();
        if(reportDate.getTime() >= visitTime.getTime() && reportDate.getTime() <= outTime.getTime()) {
            List<TEquipmentUsageRecords> tEquipmentUsageRecords = equipmentUsageRecordsMapper.selectAllUseRecordByVisitNo(visitNo);

            JSONObject dateRange = DateUtils.getReportDateRange(reportDate, 8);
            Date usageReqStartTime = dateRange.getDate("startTime");
            Date usageReqEndTime = dateRange.getDate("endTime");

            return getSleepReport(tEquipmentUsageRecords, usageReqStartTime, usageReqEndTime, reportDate);
        } else {
            return new SleepReportVo();
        }
    }

    @Override
    public SpO2ReportVo getSpO2Reports(Long visitNo, Date startTime) {
        // 获取监测数据
        List<APIMonitorPadData> monitorPadData = getReport(visitNo, startTime);
        SpO2ReportVo spO2ReportVo = fmtSpO2Data(monitorPadData);
        spO2ReportVo.setReportDate(startTime);
        return spO2ReportVo;
    }
    private SpO2ReportVo fmtSpO2Data(List<APIMonitorPadData> monitorPadData) {
        SpO2ReportVo spO2ReportVo = new SpO2ReportVo();
        if(! monitorPadData.isEmpty()) {
            List<Date> abscissa = new ArrayList<>();
            List<Integer> spO2Axis = new ArrayList<>();
            List<APIMonitorPadData> timeSortedData = monitorPadData.stream()
                    .sorted(Comparator.comparing(APIMonitorPadData::getAcquisitionTime)).collect(Collectors.toList());
            timeSortedData.forEach(e -> {
                Integer spo2 = e.getSpo2();
                if (spo2 != null) {
                    abscissa.add(e.getAcquisitionTime());
                    spO2Axis.add(spo2);
                }
            });

            spO2ReportVo.setAbscissa(abscissa);
            spO2ReportVo.setSpO2Axis(spO2Axis);
            spO2ReportVo.setHighestSpO2(spO2Axis.stream().mapToInt(Integer::intValue).max().orElse(0));
            spO2ReportVo.setLowestSpO2(spO2Axis.stream().filter(e -> e != 0).mapToInt(Integer::intValue).min().orElse(0));
            spO2ReportVo.setAvgSpO2((int) spO2Axis.stream().filter(e -> e != 0).mapToInt(Integer::intValue).average().orElse(0));
            // 轻度(85%~90%)
            spO2ReportVo.setMildSpO2((int) spO2Axis.stream().filter(e -> e >= 85 && e <= 90).count());
            // 中度(80%~84%)
            spO2ReportVo.setModerateSpO2((int) spO2Axis.stream().filter(e -> e >= 80 && e <= 84).count());
            // 重度(80%以下)
            spO2ReportVo.setSevereSpO2((int) spO2Axis.stream().filter(e -> e > 0 && e < 80).count());
            // 低通气
            spO2ReportVo.setHypopneaTimes((int) spO2Axis.stream().filter(e -> e > 0 && e <= 90).count());
        }

        return spO2ReportVo;
    }

    @Override
    public HeartRateReportVo getHeartRateReports(Long visitNo, Date startTime) {
        // 获取监测数据
        List<APIMonitorPadData> monitorPadData = getReport(visitNo, startTime);
        HeartRateReportVo heartRateReportVo = fmtHeartRateData(monitorPadData);
        heartRateReportVo.setReportTime(startTime);
        return heartRateReportVo;
    }
    private HeartRateReportVo fmtHeartRateData(List<APIMonitorPadData> monitorPadData){
        HeartRateReportVo heartRateReportVo = new HeartRateReportVo();
        if(! monitorPadData.isEmpty()) {
            List<Date> abscissa = new ArrayList<>();
            List<Integer> heartRateAxis = new ArrayList<>();
            List<Integer> sleepHeartRate = new ArrayList<>();
            List<APIMonitorPadData> timeSortedData = monitorPadData.stream()
                    .sorted(Comparator.comparing(APIMonitorPadData::getAcquisitionTime)).collect(Collectors.toList());
            timeSortedData.forEach(e -> {
                Integer heartRate = e.getHeartRate();
                if (heartRate != null) {
                    abscissa.add(e.getAcquisitionTime());
                    heartRateAxis.add(heartRate);
                    if (SleepConstants.SLEEP_STAGE_LIGHT_SLEEP.equals(e.getSleepStage()) ||
                            SleepConstants.SLEEP_STAGE_DEEP_SLEEP.equals(e.getSleepStage())) {
                        sleepHeartRate.add(heartRate);
                    }
                }
            });

            heartRateReportVo.setAbscissa(abscissa);
            heartRateReportVo.setHeartRateAxis(heartRateAxis);
            heartRateReportVo.setHighestHeartRate(heartRateAxis.stream().mapToInt(Integer::intValue).max().orElse(0));
            heartRateReportVo.setLowestHeartRate(heartRateAxis.stream().filter(e -> e != 0).mapToInt(Integer::intValue).min().orElse(0));
            heartRateReportVo.setAvgHeartRate((int) heartRateAxis.stream().filter(e -> e != 0).mapToInt(Integer::intValue).average().orElse(0));
            // 静息心率
            // 排除小于最低心率数据
            List<Integer> collect = sleepHeartRate.stream().filter(e -> e >= heartRateReportVo.getLowestHeartRate()).collect(Collectors.toList());
            heartRateReportVo.setRHeartRate((int) collect.stream().mapToInt(Integer::intValue).average().orElse(0));
        }

        return heartRateReportVo;
    }

    @Override
    public BreathRateReportVo getBreathRateReports(Long visitNo, Date startTime) {
        // 获取监测数据
        List<APIMonitorPadData> monitorPadData = getReport(visitNo, startTime);
        BreathRateReportVo breathRateReportVo = fmtBreathRateData(monitorPadData);
        breathRateReportVo.setReportDate(startTime);
        return breathRateReportVo;
    }
    private BreathRateReportVo fmtBreathRateData(List<APIMonitorPadData> monitorPadData){
        BreathRateReportVo breathRateReportVo = new BreathRateReportVo();
        if(! monitorPadData.isEmpty()) {
            List<Date> abscissa = new ArrayList<>();
            List<Integer> breathRateAxis = new ArrayList<>();
            List<APIMonitorPadData> timeSortedData = monitorPadData.stream()
                    .sorted(Comparator.comparing(APIMonitorPadData::getAcquisitionTime)).collect(Collectors.toList());
            List<APIMonitorPadData> lessThanOrEqualFiveData = new ArrayList<>();
            timeSortedData.forEach(e -> {
                Integer breathRate = e.getBreathRate();
                if (breathRate != null) {
                    abscissa.add(e.getAcquisitionTime());
                    breathRateAxis.add(breathRate);

                    if(breathRate > 0 && breathRate <= 5) {
                        lessThanOrEqualFiveData.add(e);
                    }
                }
            });

            breathRateReportVo.setAbscissa(abscissa);
            breathRateReportVo.setBreathRateAxis(breathRateAxis);
            breathRateReportVo.setHighestBreathRate(breathRateAxis.stream().mapToInt(Integer::intValue).max().orElse(0));
            breathRateReportVo.setLowestBreathRate(breathRateAxis.stream().filter(e -> e != 0).mapToInt(Integer::intValue).min().orElse(0));
            breathRateReportVo.setAvgBreathRate((int) breathRateAxis.stream().filter(e -> e != 0).mapToInt(Integer::intValue).average().orElse(0));
            breathRateReportVo.setLessThanOrEqualFiveCount(lessThanOrEqualFiveData.size());
            breathRateReportVo.setLessThanOrEqualFiveData(lessThanOrEqualFiveData);
            // 呼吸暂停
            breathRateReportVo.setApneaTimes((int) timeSortedData.stream().filter(e -> SleepConstants.SLEEP_STATUS_IN_BED.equals(e.getSleepStatus()) && e.getBreathRate() == 0).count());
        }

        return breathRateReportVo;
    }

    private List<APIMonitorPadData> getReport(Long visitNo, Date startTime){
        // 获取患者开单时间和出院时间
        PatVisitIntervalData intervalData = getTimes(visitNo);
        Date visitTime = intervalData.getVisitTime();
        Date outTime = intervalData.getOutTime();

        Calendar cal = Calendar.getInstance();
        cal.setTime(startTime);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        Date reportDate = cal.getTime();
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        Date reportDateEnd = cal.getTime();
        // 报告日期是否开单时间当天
        boolean isVisitTimeSameDay = visitTime.getTime() >= reportDate.getTime() && visitTime.getTime() <= reportDateEnd.getTime();

        List<APIMonitorPadData> monitorPadDataList = new ArrayList<>();
        if((reportDate.getTime() >= visitTime.getTime() && reportDate.getTime() <= outTime.getTime()) || isVisitTimeSameDay ) {
            // 获取使用记录
            List<TEquipmentUsageRecords> tEquipmentUsageRecords = equipmentUsageRecordsMapper.selectAllUseRecordByVisitNo(visitNo);
            JSONObject dateRange = DateUtils.getReportDateRange(reportDate, 18);
            Date usageReqStartTime = dateRange.getDate("startTime");
            // 如果报告日期是开单当天，则从开单时间开始获取数据
            if(isVisitTimeSameDay) {
                usageReqStartTime = visitTime;
            }
            Date usageReqEndTime = dateRange.getDate("endTime");
            // 获取监测数据
            return doRemoteGetData(tEquipmentUsageRecords, usageReqStartTime, usageReqEndTime.after(outTime) ? outTime : usageReqEndTime);
        }
        return monitorPadDataList;
    }

    private List<APIMonitorPadData> doRemoteGetData(List<TEquipmentUsageRecords> tEquipmentUsageRecords, Date startTime, Date endTime){
        List<APIMonitorPadData> monitorPadDataList = new ArrayList<>();
        for (TEquipmentUsageRecords usageRecord : tEquipmentUsageRecords) {
            if (EquipmentConstants.EQUIPMENT_TYPE_MONITOR_PAD_TYPE.equals(usageRecord.getEquipmentType())) {
                //查询设备在该时间段采集的数据
                RecordsReq recordsReq = new RecordsReq();
                recordsReq.setEquipmentNo(usageRecord.getEquipmentNo());
                recordsReq.setStartTime(startTime);
                recordsReq.setEndTime(endTime);
                R<MonitorPadRecords> monitorPadRecordsResult = remoteTJ01DataService.tj01Data(recordsReq, SecurityConstants.INNER);
                if (StringUtils.isNotNull(monitorPadRecordsResult)) {
                    if (R.FAIL == monitorPadRecordsResult.getCode()
                            || StringUtils.isNull(monitorPadRecordsResult.getData())
                            || StringUtils.isNull(monitorPadRecordsResult.getData().getMonitorPadDataList())) {
                        log.error("查询设备采集数据出错：" + usageRecord.getEquipmentNo() + "," + startTime + "-" + endTime);
                    }
                    monitorPadDataList.addAll(monitorPadRecordsResult.getData().getMonitorPadDataList());
                } else {
                    log.error("查询设备采集数据出错：" + usageRecord.getEquipmentNo() + "," + startTime + "-" + endTime);
                }
            }
        }
        return monitorPadDataList;
    }

    private SleepReportVo getSleepReport(List<TEquipmentUsageRecords> tEquipmentUsageRecords, Date startTime, Date endTime, Date reportDate) {
        if (tEquipmentUsageRecords.isEmpty()) {
            return null;
        }
        List<PatientSleepStageRecord> sleepStageRecordList = new ArrayList<>();
        for (TEquipmentUsageRecords usageRecord : tEquipmentUsageRecords) {
            if (EquipmentConstants.EQUIPMENT_TYPE_MONITOR_PAD_TYPE.equals(usageRecord.getEquipmentType())) {
                Date usageStartTime = usageRecord.getStartTime();
                Date usageEndTime = usageRecord.getEndTime();
                if (usageEndTime == null) {
                    usageEndTime = new Date();
                }
                if (startTime.before(usageStartTime) && startTime.after(usageEndTime)) {
                    return null;
                }
                if (startTime.before(usageStartTime)) {
                    startTime = usageStartTime;
                }
                if (endTime.after(usageEndTime)) {
                    endTime = usageEndTime;
                }
                SleepStageReq req = new SleepStageReq();
                req.setEquipmentNo(usageRecord.getEquipmentNo());
                req.setStartTime(startTime);
                req.setEndTime(endTime);
                R<SleepStageRecords> remoteStageRecordResult = remoteTJ01DataService.tj01StageRecords(req, SecurityConstants.INNER);
                if (StringUtils.isNotNull(remoteStageRecordResult)) {
                    if (R.FAIL != remoteStageRecordResult.getCode()) {
                        if (StringUtils.isNull(remoteStageRecordResult.getData())) {
                            return null;
                        }
                        SleepStageRecords sleepStageRecords = remoteStageRecordResult.getData();
                        if (sleepStageRecords != null && !sleepStageRecords.getSleepStageRecordList().isEmpty()) {
                            List<PatientSleepStageRecord> sleepStageRecordListTemp = sleepStageRecords.getSleepStageRecordList();

                            PatientSleepStageRecord patientSleepStageRecord = sleepStageRecordListTemp.get(0);
                            if(patientSleepStageRecord != null) {
                                String sleepStage = patientSleepStageRecord.getSleepStage();
                                if(!SleepConstants.SLEEP_STATUS_OUT_BED.equals(sleepStage)) {
                                    // 如果第一条数据不是离床（通常发生在躺上垫子之后，再操作开单）
                                    PatientSleepStageRecord outBedRecord = new PatientSleepStageRecord();
                                    BeanUtils.copyProperties(patientSleepStageRecord, outBedRecord);
                                    outBedRecord.setAcquisitionTime(usageStartTime);
                                    outBedRecord.setSleepStage(SleepConstants.SLEEP_STATUS_OUT_BED);

                                    sleepStageRecordList.add(outBedRecord);
                                }
                            }

                            sleepStageRecordList.addAll(sleepStageRecordListTemp);
                        }
                    } else {
                        log.error("查询睡眠状态变化记录表失败:" + usageRecord.getEquipmentNo() + "," + usageStartTime + "-" + usageEndTime);
                    }
                } else {
                    log.error("查询睡眠状态变化记录表失败:" + usageRecord.getEquipmentNo() + "," + usageStartTime + "-" + usageEndTime);
                }
            }
        }

        //查询设备在该时间段采集的数据
        List<APIMonitorPadData> monitorPadData = doRemoteGetData(tEquipmentUsageRecords, startTime, endTime);
        List<APIMonitorPadData> collect = monitorPadData.stream()
                .filter(e -> SleepConstants.SLEEP_BODYMOVE_TRUE.equals(e.getBodyMove())).collect(Collectors.toList());
        int bodyMoveCount = collect.size();

        // 计算睡眠时间
        SleepTime sleepTime = ReportUtil.calculateSleepTime(sleepStageRecordList);
        SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm:ss");
        String bodyMove = "";
        SleepReportVo sleepReportVo = new SleepReportVo();
        sleepReportVo.setReportTime(reportDate);
        sleepReportVo.setSleepWakingDuration(DateUtils.toDhmsStyle(sleepTime.getAwakeTime()));
        sleepReportVo.setSleepWakingDurationSource(sleepTime.getAwakeTime());
        sleepReportVo.setDeepSleepDuration(DateUtils.toDhmsStyle(sleepTime.getDeepSleepTime()));
        sleepReportVo.setDeepSleepDurationSource(sleepTime.getDeepSleepTime());
        sleepReportVo.setLightSleepDuration(DateUtils.toDhmsStyle(sleepTime.getLightSleepTime()));
        sleepReportVo.setLightSleepDurationSource(sleepTime.getLightSleepTime());
        sleepReportVo.setSleepDuration(DateUtils.toDhmsStyle(sleepTime.getTotalSleepTime()));
        sleepReportVo.setSleepDurationSource(sleepTime.getTotalSleepTime());
        sleepReportVo.setSleepTimeStr(sleepTime.getGoBedTime() != null ? sdfTime.format(sleepTime.getGoBedTime()) : null);
        sleepReportVo.setOutBedDuration(DateUtils.toDhmsStyle(sleepTime.getOutBedTime()));
        sleepReportVo.setOutBedDurationSource(sleepTime.getOutBedTime());
        sleepReportVo.setWakeUpTimeStr(sleepTime.getLastOutBed() != null ? sdfTime.format(sleepTime.getLastOutBed()) : null);
        sleepReportVo.setSleepTime(sleepTime.getGoBedTime());
        sleepReportVo.setWakeUpTime(sleepTime.getLastOutBed());
        bodyMove = bodyMoveCount < 20 ? "低" : (bodyMoveCount < 50 ? "中" : "高");
        sleepReportVo.setBodymoveStatus(bodyMove);
        sleepReportVo.setBodymoveCount(bodyMoveCount);
        sleepReportVo.setGetUpCount(String.valueOf(sleepTime.getGetUpCount()));
        List<SleepStageRecordsVo> sleepStageRecordsVoList = ObjectConversionUtils.copy(sleepStageRecordList, SleepStageRecordsVo.class);
        sleepReportVo.setStageRecordsList(sleepStageRecordsVoList);
        return sleepReportVo;
    }

    private PatVisitIntervalData getTimes(Long visitNo) {
        // 查询患者信息
        TPatVisit tPatVisit = patVisitMapper.selectTPatVisitByVisitNo(visitNo);
        if (tPatVisit == null) {
            throw new ServiceException("患者信息不存在！");
        }
        return DateUtils.getIntervalTime(tPatVisit.getVisitTime(), tPatVisit.getRentalDays(), tPatVisit.getOutTime(), tPatVisit.getDataType());
    }

    @Override
    public ScreenSignVo getPatSign(Long visitNo, Date startTime, Date endTime) {
        // 获取患者开单时间和出院时间
        PatVisitIntervalData intervalData = getTimes(visitNo);
        Date visitTime = intervalData.getVisitTime();
        Date outTime = intervalData.getOutTime();
        if((startTime != null && endTime == null && startTime.after(outTime)) ||
                (startTime != null && endTime != null && endTime.before(visitTime))) {
            // 查询开始日期在出院时间后或者查询结束时间在开单时间前，直接返回
            return new ScreenSignVo();
        }
        if(startTime != null && startTime.before(visitTime)){
            // 查询开始时间在开单时间前，将查询开始时间设为开单时间
            startTime = visitTime;
        }
        if(endTime != null && endTime.after(outTime)){
            // 查询结束时间在出院时间后，将查询结束时间设为出院时间
            endTime = outTime;
        }

        RecordsReq req = new RecordsReq();
        List<APIMonitorPadData> monitorPadDataList = new ArrayList<>();
        TEquipmentUsageRecords usageRecord = equipmentUsageRecordsMapper.listRecordsByVisitNoAndTimeRange(visitNo, startTime, endTime);
        Date useStart = usageRecord.getStartTime();
        Date useEnd = usageRecord.getEndTime() == null ? new Date() : usageRecord.getEndTime();
        if(startTime.before(useEnd) || endTime.after(useStart)) {
            req.setVisitNo(visitNo);
            req.setStartTime(startTime.before(useStart) ? useStart : startTime);
            req.setEndTime(endTime.after(useEnd) ? useEnd: endTime);
            req.setEquipmentNo(usageRecord.getEquipmentNo());

            if (EquipmentConstants.EQUIPMENT_TYPE_MONITOR_PAD_TYPE.equals(usageRecord.getEquipmentType())) {
                R<MonitorPadRecords> monitorPadRecordsResult = remoteTJ01DataService.tj01Data(req, SecurityConstants.INNER);
                if (monitorPadRecordsResult.getCode() == HttpStatus.SUCCESS && monitorPadRecordsResult.getData() != null) {
                    monitorPadDataList.addAll(monitorPadRecordsResult.getData().getMonitorPadDataList());
                } else {
                    log.error(monitorPadRecordsResult.getMsg());
                }
            }
        }

        List<Date> heartRateAbscissa = new ArrayList<>();
        List<Integer> heartRateAxis = new ArrayList<>();
        List<Date> breathRateAbscissa = new ArrayList<>();
        List<Integer> breathRateAxis = new ArrayList<>();
        List<Date> spO2Abscissa = new ArrayList<>();
        List<Integer> spo2Axis = new ArrayList<>();
        monitorPadDataList.forEach(e -> {
            if (e.getHeartRate() != null) {
                heartRateAbscissa.add(e.getAcquisitionTime());
                heartRateAxis.add(e.getHeartRate());
            }
            if (e.getBreathRate() != null) {
                breathRateAbscissa.add(e.getAcquisitionTime());
                breathRateAxis.add(e.getBreathRate());
            }
            if (e.getSpo2() != null) {
                spO2Abscissa.add(e.getAcquisitionTime());
                spo2Axis.add(e.getSpo2());
            }
        });
        HeartRateVo heartRateVo = new HeartRateVo();
        heartRateVo.setHeartRateAbscissa(heartRateAbscissa);
        heartRateVo.setHeartRateAxis(heartRateAxis);
        BreathRateVo breathRateVo = new BreathRateVo();
        breathRateVo.setBreathRateAbscissa(breathRateAbscissa);
        breathRateVo.setBreathRateAxis(breathRateAxis);
        SpO2Vo spO2Vo = new SpO2Vo();
        spO2Vo.setSpO2Axis(spo2Axis);
        spO2Vo.setSpO2Abscissa(spO2Abscissa);

        ScreenSignVo screenSignVo = new ScreenSignVo();
        screenSignVo.setHeartRateVo(heartRateVo);
        screenSignVo.setBreathRateVo(breathRateVo);
        screenSignVo.setSpO2Vo(spO2Vo);
        return screenSignVo;
    }

    @Override
    public List<TJ01ReportsDataVo> getSleepReportData(TJ01ReportsDataReq req) {
        String visitNos = req.getVisitNos();
        String reportItems = req.getReportItems();
        Date reportDate = new Date();
        if(StringUtils.isNotBlank(req.getReportDate())) {
            reportDate = DateUtils.parseDate(req.getReportDate());
        }

        // 需要打印的报告项目
        List<String> reportItemList = Arrays.stream(reportItems.split(",")).collect(Collectors.toList());
        if(!reportItemList.contains(ReportConstant.BRACELET_SPO2) &&
                !reportItemList.contains(ReportConstant.BRACELET_TEMPERATURE) &&
                !reportItemList.contains(ReportConstant.BRACELET_HEART_RATE)) {
            System.err.println("不支持的报告类型：" + reportItems);
            throw new ServiceException("不支持的报告类型！");
        }

        List<TJ01ReportsDataVo> reportsDataVoList = new ArrayList<>();
        // 所有就诊记录
        List<String> visitNoList = Arrays.stream(visitNos.split(",")).collect(Collectors.toList());
        for (String visitNoStr : visitNoList) {
            Long visitNo = Long.valueOf(visitNoStr);
            // 查询患者信息
            PatientDetailInfoVo detailInfo = patVisitMapper.getDetailInfo(visitNo);
            // 查询报告数据
            List<APIMonitorPadData> apiMonitorPadData = getReport(visitNo, reportDate);

            TJ01ReportsDataVo vo = new TJ01ReportsDataVo();
            vo.setPatInfo(detailInfo);

            if(! apiMonitorPadData.isEmpty()) {
                for (String item : reportItemList) {
                    getReportDataVo(apiMonitorPadData, item, vo);

                    vo.setSleepReportVo(this.sleep(visitNo, reportDate));
                }
            }

            reportsDataVoList.add(vo);
        }

        return reportsDataVoList;
    }

    /**
     * 获取报告数据
     */
    private void getReportDataVo(List<APIMonitorPadData> apiMonitorPadData, String item, TJ01ReportsDataVo vo) {
        if(vo == null) {
            vo = new TJ01ReportsDataVo();
        }
        if(ReportConstant.MONITOR_PAD_SPO2.equals(item)) {
            // 血氧
            vo.setSpO2ReportVo(fmtSpO2Data(apiMonitorPadData));
        }
        if(ReportConstant.MONITOR_PAD_HEART_RATE.equals(item)) {
            // 心率
            vo.setHeartRateReportVo(fmtHeartRateData(apiMonitorPadData));
        }
        if(ReportConstant.MONITOR_PAD_BREATH_RATE.equals(item)) {
            // 呼吸
            vo.setBreathRateReportVo(fmtBreathRateData(apiMonitorPadData));
        }
    }
}
